package com.sinheldrin.musicplayer.player
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;

	/**
	 * Wrapper on the youtube chromeless player.
	 * 
	 * <p>See https://developers.google.com/youtube/flash_api_reference</p>
	 */
	public class YoutubePlayerWrapper implements IEventDispatcher
	{
		public function YoutubePlayerWrapper(player:Object)
		{
			_player = player;
		}
		
		private var _player:Object = null;
		
		public static const QUALITY_MEDIUM:String = "medium";
		
		/**
		 * Loads the specified video's thumbnail and prepares the player to play the video.
		 * The player does not request the FLV until playVideo() or seekTo() is called.
		 * 
		 * @param videoId
		 * Specifies the YouTube Video ID of the video to be played.
		 * In YouTube Data API video feeds, the <yt:videoid> tag specifies the ID.
		 * 
		 * @param startSeconds
		 * Specifies the time from which the video should start playing when playVideo() is called.
		 * If you specify a startSeconds value and then call seekTo(), then the player plays from the time specified in the seekTo() call.
		 * When the video is cued and ready to play, the player will broadcast a video cued event (5).
		 * 
		 * @param suggestedQuality
		 * Specifies the suggested playback quality for the video.
		 * Please see the definition of the setPlaybackQuality function for more information about playback quality. 
		 */
		public function cueVideoById(videoId:String, startSeconds:Number = 0, suggestedQuality:String = QUALITY_MEDIUM):void
		{
			_player.cueVideoById(videoId, startSeconds, suggestedQuality);
		}
		
		/**
		 * Loads and plays the specified video.
		 * 
		 * @param videoId
		 * Specifies the YouTube Video ID of the video to be played.
		 * In YouTube Data API video feeds, the <yt:videoid> tag specifies the ID.
		 * 
		 * @param startSeconds
		 * The video will start from the closest keyframe to the specified time.
		 * 
		 * @param suggestedQuality
		 * Specifies the suggested playback quality for the video.
		 * Please see the definition of the setPlaybackQuality function for more information about playback quality.
		 */
		public function loadVideoById(videoId:String, startSeconds:Number = 0, suggestedQuality:String = QUALITY_MEDIUM):void
		{
			_player.loadVideoById(videoId, startSeconds, suggestedQuality);
		}
		
		/**
		 * Plays the currently cued/loaded video. The final player state after this function executes will be playing (1).
		 * 
		 * <p>Note: YouTube only counts playbacks that are initiated through a native play button in either the embedded or chromeless player.</p>
		 */
		public function playVideo():void
		{
			_player.playVideo();
		}
		
		/**
		 * Pauses the currently playing video.
		 * The final player state after this function executes will be paused (2)
		 * unless the player is in the ended (0) state when the function is called,
		 * in which case the player state will not change.
		 */
		public function pauseVideo():void
		{
			_player.pauseVideo();
		}
		
		/**
		 * Stops and cancels loading of the current video.
		 * This function should be reserved for rare situations
		 * when you know that the user will not be watching additional video in the player.
		 * If your intent is to pause the video, you should just call the pauseVideo function.
		 * If you want to change the video that the player is playing,
		 * you can call one of the queueing functions without calling stopVideo first.
		 * 
		 * <p><strong>Important</strong>: Unlike the pauseVideo function, which leaves the player in the paused (2) state,
		 * the stopVideo function could put the player into any not-playing state,
		 * including ended (0), paused (2), video cued (5) or unstarted (-1).</p>
		 */
		public function stopVideo():void
		{
			_player.stopVideo();
		}
		
		/**
		 * Seeks to a specified time in the video.
		 * If the player is paused when the function is called, it will remain paused.
		 * If the function is called from another state (playing, video cued, etc.), the player will play the video.
		 * 
		 * @param seconds Identifies the time to which the player should advance.
		 * <p>The player will advance to the closest keyframe before that time
		 * unless the player has already downloaded the portion of the video to which the user is seeking.
		 * In that case, the player will advance to the closest keyframe
		 * before or after the specified time as dictated by the seek() method of the Flash player's NetStream object.
		 * (See Adobe's documentation for more information.)</p>
		 * 
		 * @param allowSeekAhead Determines whether the player will make a new request to the server
		 * if the seconds parameter specifies a time outside of the currently buffered video data.
		 * 
		 * <p>We recommend that you set this parameter to false while the user drags the mouse along a video progress bar
		 *  and then set it to true when the user releases the mouse.
		 * This approach lets a user scroll to different points of a video
		 * without requesting new video streams by scrolling past unbuffered points in the video.
		 * When the user releases the mouse button, the player advances to the desired point in the video
		 * and requests a new video stream if necessary.</p>
		 */
		public function seekTo(seconds:Number, allowSeekAhead:Boolean):void
		{
			_player.seekTo(seconds, allowSeekAhead);
		}

		/**
		 * Mute the player.
		 */
		public function mute():void
		{
			_player.mute();
		}

		/**
		 * Unmutes the player.
		 */
		public function unMute():void
		{
			_player.unMute();
		}
		
		/**
		 * @return <code>True</code> if the player is muted, <code>false</code> if not.
		 */
		public function isMuted():Boolean
		{
			return _player.isMuted();
		}
		
		/**
		 * Sets the volume. Accepts an integer between 0 and 100.
		 */
		public function setVolume(volume:Number):void
		{
			_player.setVolume(volume);
		}

		/**
		 * @return The player's current volume, an integer between 0 and 100. Note that getVolume() will return the volume even if the player is muted.
		 */
		public function getVolume():Number
		{
			return _player.getVolume();
		}
			
		/**
		 * Sets the size in pixels of the player.
		 * This method should be used instead of setting the width and height properties of the MovieClip.
		 * Note that this method does not constrain the proportions of the video player, so you will need to maintain a 4:3 aspect ratio.
		 * The default size of the chromeless SWF when loaded into another SWF is 320px by 240px and the default size of the embedded player SWF is 480px by 385px. 
		 */
		public function setSize(width:Number, height:Number):void
		{
			_player.setSize(width, height);
		}
		
		/**
		 * @return The elapsed time in seconds since the video started playing.
		 */
		public function getCurrentTime():Number
		{
			return _player.getCurrentTime();
		}
		
		/**
		 * Returns the duration in seconds of the currently playing video.
		 * Note that getDuration() will return 0 until the video's metadata is loaded,
		 * which normally happens just after the video starts playing.
		 * 
		 * <p>If the currently playing video is a live event,
		 * the getDuration() function will return the elapsed time since the live video stream began.
		 * Specifically, this is the amount of time that the video has streamed without being reset or interrupted.
		 * In addition, this duration is commonly longer than the actual event time since streaming may begin before the event's start time.</p>
		 */
		public function getDuration():Number
		{
			return _player.getDuration();
		}
		
		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			_player.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		public function dispatchEvent(event:Event):Boolean
		{
			return _player.dispatchEvent(event);
		}
		
		public function hasEventListener(type:String):Boolean
		{
			return _player.hasEventListener(type);
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			_player.removeEventListener(type, listener, useCapture);
		}
		
		public function willTrigger(type:String):Boolean
		{
			return _player.willTrigger(type);
		}
	}
}